/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package polynomialSimplifier;

import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author Nathan
 */
public class PolynomialSimplifier {

  /**
   * @param args the command line arguments
   */
  public static void main(String[] args) {

    Polynomial left = new Polynomial();
    Polynomial right = new Polynomial();

    // Read in equation off command line
    if (args.length == 0) {
      System.err.printf("Command line arguments missing.\n");
      System.err.printf("List coefficients in decreasing order seperated by a single space.\n");
      System.err.printf("Ex:\n(2x^3 - 3x^2 + 4x - 5) * (3x^3 - 2x^2 + x -7) will be entered as:\n");
      System.err.printf("'2 -3 4 -5 3 -2 1 -7' (with no single quotes).\n");
      System.exit(1);
    }
    int order = args.length / 2 - 1;
    for (int i = 0; i <= order; i++) {
      // 1st polynomial
      left.getTerms().add(new Number(Integer.parseInt(args[i]), order - i));
      // 2nd polynomial
      right.getTerms().add(new Number(Integer.parseInt(args[i + order + 1]), order - i));
    }

    // Do work
    List<Number> result = Group_r(left.getTerms(), right.getTerms(), 0, left.getTerms().size() - 1, 0, right.getTerms().size() - 1);
    result = simplify_r(result);

    // print result
    StringBuilder out = new StringBuilder();
    for (Number item : result) {
      out.append(item.toString());
    }
    out.append("\n");
    if ("- ".equals(out.substring(0, 2))) {
      out.delete(1, 2); // Switch "- " to "-"
    } else {
      out.delete(0, 2); // Remove front '+' sign
    }
    System.out.print(out.toString());
  }

  private static List<Number> Group_r(List<Number> A, List<Number> B, int startA, int endA, int startB, int endB) {
    if (startA == endA) {
      // base case    A * B;
      Number temp = new Number(A.get(startA).getCoeff() * B.get(startB).getCoeff(), A.get(startA).getPower() + B.get(startB).getPower());
      List<Number> toReturn = new ArrayList<Number>();
      toReturn.add(temp);
      return toReturn;
    }
    int midA = (startA + endA) / 2;
    int midB = (startB + endB) / 2;

    List<Number> a = Group_r(A, B, startA, midA, startB, midB);
    List<Number> b = Group_r(A, B, startA, midA, midB + 1, endB);
    List<Number> c = Group_r(A, B, midA + 1, endA, startB, midB);
    List<Number> d = Group_r(A, B, midA + 1, endA, midB + 1, endB);

    List<Number> result = new ArrayList<Number>(a);
    result.addAll(b);
    result.addAll(c);
    result.addAll(d);

    return result;
  }

  private static List<Number> simplify_r(List<Number> list) {
    List<Number> result = new ArrayList<Number>();
    result.add(list.get(0));
    for (int i = 1; i < list.size(); i++) {
      Number current = list.get(i);
      for (int j = i + 1; j < list.size(); j++) { // combine like terms loop
        Number test = list.get(j);
        if (current.getPower() == test.getPower()) {
          current.setCoeff(current.getCoeff() + test.getCoeff());
          list.remove(j--);
        }
      }
      result.add(current);
    }
    return result;
  }
//  private static List<Group> combine(List<Group> leftList, List<Group> rightList) {
//    List<Group> combined = new ArrayList<Group>();
//
//    for (Group left : leftList) {
//      for (Group right : rightList) {
//        Group group = new Group();
//        Number n1 = new Number();
//        Number n2 = new Number();
//        Number n3 = new Number();
//        Number n4 = new Number();
//
//        n1.setCoeff(1);
//        n1.setPower(left.getLeft().get(0).getPower() + right.getLeft().get(0).getPower());
//        group.getLeft().add(n1);
//
//        n2.setCoeff(left.getRight().get(0).getCoeff() * right.getRight().get(0).getCoeff());
//        n2.setPower(2);
//        group.getRight().add(n2);
//
//        n3.setCoeff((left.getRight().get(0).getCoeff() * right.getRight().get(1).getCoeff())
//                + (left.getRight().get(1).getCoeff() * right.getRight().get(0).getCoeff()));
//        n3.setPower(1);
//        group.getRight().add(n3);
//
//        n4.setCoeff(left.getRight().get(1).getCoeff() * right.getRight().get(1).getCoeff());
//        n4.setPower(0);
//        group.getRight().add(n4);
//
//        combined.add(group);
//      }
//    }
//
//    System.out.println("\n*************************");
//    for (Group item : combined) {
//      List<Number> left = item.getLeft();
//      List<Number> right = item.getRight();
//
//      for (Number n : left) {
//        System.out.printf("%dx^%d", n.getCoeff(), n.getPower());
//      }
//      System.out.print("(");
//      for (Number n : right) {
//        System.out.printf("%dx^%d ", n.getCoeff(), n.getPower());
//      }
//      System.out.println(")");
//    }
//
//    return combined;
//  }
//
//  private static List<Number> simplify(List<Group> combined) {
//    List<Number> simplified = new ArrayList<Number>();
//
//    for (Group item : combined) {
//      for (Number left : item.getLeft()) {
//        for (Number right : item.getRight()) {
//          Number temp = new Number();
//          temp.setCoeff(left.getCoeff() * right.getCoeff());
//          temp.setPower(left.getPower() + right.getPower());
//          simplified.add(temp);
//        }
//      }
//    }
//
//    for (Number item : simplified) {
//      System.out.printf("%dx^%d ", item.getCoeff(), item.getPower());
//    }
//    System.out.println();
//
//    // Combine like terms (its ugly for now)    
//    for (int i = 1; simplified.get(i).getPower() > 0; i++) {
//      Number current = simplified.get(i);
//      for (int j = i + 1; j < simplified.size(); j++) {
//        Number test = simplified.get(j);
//        if (current.getPower() == test.getPower()) {
//          current.setCoeff(current.getCoeff() + test.getCoeff());
//          simplified.remove(j--);
//        }
//      }
//    }
//
//    for (Number item : simplified) {
//      System.out.printf("%dx^%d ", item.getCoeff(), item.getPower());
//    }
//    System.out.println();
//
//    return simplified;
//  }
}
